package hunglv4.vnu;

import java.util.ArrayList;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.Menu;
import android.widget.TextView;

public class DisplayActivity extends Activity {
	ProgressDialog mProgressDialog;
	ArrayList<Integer> inputArray;
	TextView outputDisplay;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_display);

		outputDisplay = (TextView) findViewById(R.id.displayAlgorith);

		mProgressDialog = new ProgressDialog(this);
		mProgressDialog.show();

		Intent intent = getIntent();
		Bundle mBundle = intent.getBundleExtra(MainActivity.BUNDLE_VALUE_KEY);
		
		int type = mBundle.getInt(MainActivity.BUNDLE_TYPE_KEY);		
		inputArray = mBundle.getIntegerArrayList(MainActivity.BUNDLE_VALUE_KEY);
		if(inputArray.size() == 0){
			Intent mIntent = new Intent(DisplayActivity.this, MainActivity.class);
			startActivity(mIntent);
			return;
		}
		
		if (type == MainActivity.QUICK_SORT) {
			QuickSortAsyncTask mSortAsyncTask = new QuickSortAsyncTask(
					inputArray);
			mSortAsyncTask.execute();
		} else if (type == MainActivity.MERGER_SORT) {
			MergeSortAsyncTask mMergeSortAsyncTask = new MergeSortAsyncTask(
					inputArray);
			mMergeSortAsyncTask.execute();
		} else if(type == MainActivity.HEAP_SORT){
			HeapSortAsyncTask mHeapSortAsyncTask = new HeapSortAsyncTask(inputArray);
			mHeapSortAsyncTask.execute();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_display, menu);
		return true;
	}

	public class QuickSortAsyncTask extends AsyncTask<Void, String, Void> {
		private ArrayList<Integer> numbers;
		private int number;

		public QuickSortAsyncTask(ArrayList<Integer> values) {
			if (values == null || values.size() == 0) {
				return;
			}
			this.numbers = values;
			number = values.size();
		}

		@Override
		protected Void doInBackground(Void... params) {
			quicksort(0, number - 1);
			return null;
		}

		@Override
		protected void onProgressUpdate(String... strings) {
			outputDisplay.append(strings[0] + "\n");

		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			mProgressDialog.hide();
		}

		private void quicksort(int low, int high) {
			int i = low, j = high;
			int pivot = numbers.get(low + (high - low) / 2);

			String update = numbers.toString();
			publishProgress(update);

			while (i <= j) {
				while (numbers.get(i) < pivot) {
					i++;
				}

				while (numbers.get(j) > pivot) {
					j--;
				}

				if (i <= j) {
					exchange(i, j);
					i++;
					j--;
				}
			}

			if (low < j)
				quicksort(low, j);
			if (i < high)
				quicksort(i, high);
		}

		private void exchange(int i, int j) {
			int temp = numbers.get(i);
			numbers.set(i, numbers.get(j));
			numbers.set(j, temp);
		}
	}

	public class MergeSortAsyncTask extends AsyncTask<Void, String, Void> {
		private ArrayList<Integer> numbers, helper;
		private int size;

		public MergeSortAsyncTask(ArrayList<Integer> values) {
			if (values == null || values.size() == 0) {
				return;
			}
			this.numbers = values;
			size = numbers.size();
			helper = new ArrayList<Integer>();
			for (int i = 0; i < size; i++)
				helper.add(0);
		}

		@Override
		protected Void doInBackground(Void... params) {
			mergesort(0, size - 1);
			return null;
		}

		@Override
		protected void onProgressUpdate(String... strings) {
			outputDisplay.append(strings[0] + "\n");

		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			mProgressDialog.hide();
		}

		private void mergesort(int low, int high) {
			if (low < high) {
				int pivot = (low + high) / 2;
				mergesort(low, pivot);
				mergesort(pivot + 1, high);
				merge(low, pivot, high);
				publishProgress(numbers.toString());
			}
		}

		private void merge(int low, int middle, int high) {

			for (int i = low; i <= high; i++) {
				helper.set(i, numbers.get(i));
			}

			int i = low;
			int j = middle + 1;
			int k = low;

			while (i <= middle && j <= high) {
				if (helper.get(i) <= helper.get(j)) {
					numbers.set(k, helper.get(i));
					i++;
				} else {
					numbers.set(k, helper.get(j));
					j++;
				}
				k++;
			}

			while (i <= middle) {
				numbers.set(k, helper.get(i));
				k++;
				i++;
			}
		}
	}

	public class HeapSortAsyncTask extends AsyncTask<Void, String, Void> {
		private ArrayList<Integer> numbers;
		private int size;

		private int left, right, largest;

		public HeapSortAsyncTask(ArrayList<Integer> values) {
			if (values == null || values.size() == 0) {
				return;
			}
			this.numbers = values;
			size = numbers.size();
		}

		@Override
		protected Void doInBackground(Void... params) {
			buildHeap();
			for (int i = (size-1); i > 0; i--) {
				exchange(0, i);
				size --;
				maxheap(0);
				publishProgress(numbers.toString());
			}
			return null;
		}

		@Override
		protected void onProgressUpdate(String... strings) {
			outputDisplay.append(strings[0] + "\n");
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			mProgressDialog.hide();
		}

		private void buildHeap() {
			int n = (size - 1) / 2;
			for (int i = n; i >= 0; i--) {
				maxheap(i);
			}
		}

		public void maxheap(int i) {
			left = 2 * i;
			right = 2 * i + 1;
			if (left <= (size - 1) && numbers.get(left) > numbers.get(i)) {
				largest = left;
			} else {
				largest = i;
			}

			if (right <= (size - 1)
					&& numbers.get(right) > numbers.get(largest)) {
				largest = right;
			}
			if (largest != i) {
				exchange(i, largest);
				maxheap(largest);
			}
		}

		private void exchange(int i, int j) {
			int t = numbers.get(i);
			numbers.set(i, numbers.get(j));
			numbers.set(j, t);
		}
	}
}
